-
-
Notifications
You must be signed in to change notification settings - Fork 265
Add V2 Importer for Tuxcare advisories #2104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Sampurna Pyne <[email protected]>
ziadhany
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Samk1710 Thanks , see feedback and suggestions below
vulnerabilities/tests/pipelines/v2_importers/test_tuxcare_importer_v2.py
Outdated
Show resolved
Hide resolved
Signed-off-by: Sampurna Pyne <[email protected]>
|
@ziadhany Thanks for your review. |
| summary = f"TuxCare advisory for {cve_id}" | ||
| if project_name: | ||
| summary += f" in {project_name}" | ||
| if os_name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is wrong. The OS name should be considered a qualifier.
Please look at https://github.com/package-url/purl-spec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran a small local script on the data source JSON file to find the unique OS names.
CentOS: 23778
Ubuntu: 13934
Oracle: 8190
AlmaLinux: 6562
Unknown: 4526
CloudLinux: 1934
RHEL: 1524
Debian: 944
TuxCare: 792
Alpine: 119
Idea is to map these with the appropriate PURLs. Will be implementing this and pushing the changes shortly.
Do let me know if any other approach is more suitable. Thanks for the correction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ziadhany
I had a quick question: while looking through the importers I came across some parity with the qualifier field in PURL. I went with qualifiers["os"] = os_name. Was a little confused if it should be distro though. If you could kindly guide me on this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Samk1710 Yes, I think it should be distro.
I also think we should remove summary, it doesn’t make sense to me.
I think the purl should look like this:
pkg:generic/tuxcare/project_name@version?distro=os_name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification. I'll remove the summary, it is in fact redundant.
|
@Samk1710, could you please also fix the CI ? |
…o add-tuxcare-importer
Signed-off-by: Sampurna Pyne <[email protected]>
…lnerablecode into add-tuxcare-importer
|
Hey @ziadhany |
Signed-off-by: Sampurna Pyne <[email protected]>
Signed-off-by: Sampurna Pyne <[email protected]>
|
Hey @ziadhany |
Signed-off-by: Sampurna Pyne <[email protected]>
ziadhany
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Samk1710 , The code looks good. I think we just need some refinement of the package URL and the affected and fixed versions.
| if not cve_id or not cve_id.startswith("CVE-"): | ||
| continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid silently skipping this
|
|
||
| return PackageURL( | ||
| type="generic", namespace="tuxcare", name=project_name, qualifiers=qualifiers | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Samk1710 I think this purl is incorrect, sorry for the confusion.
I noticed that TuxCare provides security patches for Endless Lifecycle Support (ELS), delivering qualified security and selected bug-fix errata advisories across all architectures.
So, I think the correct way to do this is that we should create a mapping.
cve "CVE-2024-50006"
os_name "Ubuntu 16.04 ELS"
project_name "linux-hwe"
version "4.15.0"
score "4.7"
severity "MEDIUM"
status "Needs Triage"
pkg:deb/ubuntu/[email protected]?distro=ubuntu-16.04-els
For unknown OS, use generic.
| logger.warning(f"Failed to parse date {last_updated} for {cve_id}: {e}") | ||
|
|
||
| yield AdvisoryData( | ||
| advisory_id=advisory_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Advisory_id should be unique, so drop the old database and run the importer again to ensure there is no duplication
from vulnerabilities.models import AdvisoryV2
from django.db.models import Count
duplicates = (
AdvisoryV2.objects
.values('avid')
.annotate(count=Count('id'))
.filter(count__gt=1)
)
len(duplicates)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ziadhany!
I've analyzed the data and found duplicate advisory IDs in the database. This happens because TuxCare structures their data with the same CVE ID across different OS distributions, packages, and versions - each record represents the same CVE but for a specific OS+package+version combination.
For example, CVE-2023-52922 appears in 17 different records:
{
"cve": "CVE-2023-52922",
"os_name": "CloudLinux 7 ELS",
"project_name": "squid",
"version": "3.5.20",
"status": "In Testing"
}
{
"cve": "CVE-2023-52922",
"os_name": "Oracle Linux 7 ELS",
"project_name": "squid",
"version": "3.5.20",
"status": "In Testing"
}
{
"cve": "CVE-2023-52922",
"os_name": "CentOS 8.4 ELS",
"project_name": "squid",
"version": "4.11-4",
"status": "Ignored"
}
{
"cve": "CVE-2023-52922",
"os_name": "CentOS 8.5 ELS",
"project_name": "kernel",
"version": "4.18.0",
"score": "7.8",
"severity": "HIGH",
"status": "Released",
"last_updated": "2025-05-21 01:43:28.677045"
}Workaround
-- use a composite advisory_id like {cve_id}-{normalized_os}-{project_name}-{version}
-- CVE-2023-52922-cloudlinux-7-els-squid-3.5.20 and CVE-2023-52922-oracle-linux-7-els-squid-3.5.20
-- add CVE_ID to aliases: ["CVE-2023-52922"]
This way each OS+package+version combination gets a unique advisory, the CVE remains searchable via aliases, and we avoid duplicates.
Does this approach work for you? Do share your suggestions.
Also, just a heads up - the TuxCare endpoint is currently returning a 500 error, it might take some time before I can run the importer and verify everything works as expected.
| affected_version_range = None | ||
| if version: | ||
| try: | ||
| affected_version_range = GenericVersionRange.from_versions([version]) | ||
| except ValueError as e: | ||
| logger.warning(f"Failed to parse version {version} for {cve_id}: {e}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we assuming that all versions are affected? According to my understanding, different versions can have different statuses:
- In Progress
- In Testing
- In Rollout
- Needs Triage
- Not Vulnerable
- Already Fixed
- Ignored
Addresses Issue:
Data Source: https://cve.tuxcare.com/els/download-json?orderBy=updated-desc
Importer Log Excerpt: